from nbhttpconnection import NBHTTPConnection
import time, re, urllib, socket

def EpisodeLookup(req, debug=False):
    req = str(req)
    result = Lookup(req, debug)
    if(result != None):
        return result
    if(req.find('and') != -1):
        req = req.replace('and', '&')
        result = Lookup(req, debug)
        if(result != None):
            return result
    if(req.count(' ') <= 1):
        loop = False
    else:
        loop = True
    while (loop):
        req = req[:req.rfind(' ')]            
        result = Lookup(req, debug)
        if(result != None):
            return result
        if(req.count(' ') <= 1):
            loop = False
    return None

def Lookup(req, debug=False):
    input = req
    req = urllib.urlencode({'seriesname' : req})
    if debug:
        print "[Follwit Episode Lookup] Running lookup for: " + req
    host = 'www.thetvdb.com'
    req = "/api/GetSeries.php?" + req
    try:
        conn = NBHTTPConnection(host)
    except socket.timeout:
        print '[Follwit API] socket timeout excecption'
        conn = None
    if conn == None:
        if debug:
            print 'Unable to connect to thetvdb'
        return    
    try:
        conn.request('GET', req)
    except socket.error:
        if debug:
            print 'Unable to connect to thetvdb'
        conn.close()
        return
    
    conn.go()
    
    timeout = 0
    while timeout < 60:
        if conn.hasResult():
            break
        timeout = timeout + 1
        time.sleep(1)
    
    if timeout == 60:
        if debug:
            print '[Follwit Episode Lookup] Request has timed out.'
        conn.close()
        return
    
    response = conn.getResult()
    raw = response.read()
    
    if debug:
        print "[Follwit Episode Lookup] Raw responce " + raw
    
    conn.close()
    
    match = re.findall(r'<seriesid>(\d+)</seriesid>.+?<SeriesName>(.+?)<', raw, re.IGNORECASE + re.DOTALL)
    result = None
    try:
        for res in match:
            if levenshtein(res[1], input) < 5:
                result = res[0]
                break
    except:
        result = None
    
    return result
        
def levenshtein(s1, s2):
    l1 = len(s1)
    l2 = len(s2)

    matrix = [range(l1 + 1)] * (l2 + 1)
    for zz in range(l2 + 1):
      matrix[zz] = range(zz,zz + l1 + 1)
    for zz in range(0,l2):
      for sz in range(0,l1):
        if s1[sz] == s2[zz]:
          matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])
        else:
          matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)
    return matrix[l2][l1]